<template>
  <!-- visible是饿了么ui自带的属性值 用于控制显示与隐藏 传入布尔类型值 默认是false -->
  <!-- 绑定点击事件 控制器显示与隐藏效果 before-close是饿了么ui提供的 点击删除按钮 关闭表单 -->
  <el-dialog title="编辑部门" :visible="isShowDeptEdit" :before-close="handleClose" @open="handleOpen">
    <!-- 绑定表单验证的规则 async-validator表单验证 需要用 :rules 和 v-model 动态绑定表单验证 -->
    <!-- rules是绑定规则 v-model是绑定用户输入 -->
    <!-- ref直接操作dom 进行数据提交 -->
    <el-form ref="addForm" label-width="120px" :rules="rules" :model="form">
      <!-- prop绑定rules里面的表单验证规则 -->
      <el-form-item label="部门名称" prop="name">
        <!-- 需要用到双向绑定 v-model 来双向绑定用户输入的值 进行表单验证 -->
        <el-input v-model="form.name" style="width:80%" placeholder="1-50个字符" />
      </el-form-item>
      <el-form-item label="部门编码" prop="code">
        <el-input v-model="form.code" style="width:80%" placeholder="1-50个字符" />
      </el-form-item>
      <el-form-item label="部门负责人" prop="manager">
        <el-select v-model="form.manager" style="width:80%" placeholder="请选择">
          <!-- value表示表单获取到的值 label表示页面显示的信息 提交表单时候需求 -->
          <el-option v-for="item in plist" :key="item.id" :value="item.username" :label="item.username" />
        </el-select>
      </el-form-item>
      <el-form-item label="部门介绍" prop="introduce">
        <el-input v-model="form.introduce" style="width:80%" placeholder="1-300个字符" type="textarea" :rows="3" />
      </el-form-item>
    </el-form>
    <!-- el-dialog有专门放置底部操作栏的 插槽  具名插槽 -->
    <div slot="footer">
      <el-button type="primary" size="small" @click.native="addThis">确定</el-button>
      <!-- 绑定点击事件 控制器显示与隐藏效果 -->
      <el-button size="small" @click.native="handleClose">取消</el-button>
    </div>
  </el-dialog>
</template>
<script>
// 导入获取部门负责人的api接口
import { getEmployeeSimple } from '../api/employees'
// 导入 获取当前表单信息的api接口 导入修改表单数据后上传的api接口
import { reqGetDepartDetail, reqUpdateDepartments } from '@/api/departments.js'
//! 所有的表单验证规则效验 都绑定在el-form里面
export default {
  name: 'AddDept',
  props: {
    // 控制弹窗显示
    isShowDeptEdit: {
      required: true
    },
    // 导入点击部门的详细信息
    deptId: {
      required: true
    },
    // 所有部门的数据
    allId: {
      required: true
    }
  },
  data () {
    return {
      // 负责人列表
      plist: [],
      // 接收用户输入的数值 需要和表单验证的rules里面的 属性名一致 才能调用效验
      //! 所有的表单验证规则效验 都绑定在el-form里面
      form: {
        name: '', // 部门名称
        code: '', // 部门编码
        manager: '', // 部门管理者
        introduce: '' // 部门介绍
      },
      // 设置表单验证 这个表单但是是饿了么调用第三方组件 实现的二次封装表单验证(二次封装的是 async-validator表单验证插件)
      rules: {
        name: [ // 部门名称
          // required是必填项 message是错误提示信息 trigger是事件监听类型 blur焦点失去时 change修改数据时
          { required: true, message: '部门名称不能为空', trigger: ['blur', 'change'] },
          // min是最小输入 max是最大输入
          { min: 1, max: 50, message: '部门名称要求1-50个字符', trigger: ['blur', 'change'] },
          // 设置自定义表单验证事件 validator饿了么ui提供的自定义表单验证生成 (自动验证写在Vue的data()属性中)
          // ~ 验证规则: 同级部门编码的名称不可以重复
          { validator: this.validateCode, trigger: ['blur'] }
        ],
        code: [ // 部门编码
          { required: true, message: '部门编码不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 50, message: '部门编码要求1-50个字符', trigger: ['blur', 'change'] },
          // ? 验证规则: 同级部门名称不可以重复
          { validator: this.validateName, trigger: ['blur'] }
        ],
        manager: [ // 部门负责人
          { required: true, message: '部门负责人不能为空', trigger: ['blur', 'change'] }
        ],
        introduce: [ // 部门介绍
          { required: true, message: '部门介绍不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 300, message: '部门介绍要求1-300个字符', trigger: ['blur', 'change'] }
        ]
      }
    }
  },
  methods: {
    // ~ 设置编辑部门的方法效验
    // ~ -------- 规则: 判断 不可以和同级重名 父级部门 子级部门不影响 可以重复id
    validateCode (rule, value, callback) {
      // ~ 同级部门的名称不可以重复
      // ~ 1.找到当前同级部门信息 根据父级部门的id
      const depts = this.allId.filter(item => {
        // 设置条件 return返回查询到的所在部门信息
        return item.pid === this.deptId.pid
      })
      // ~ 2、判断输入的部门名称和同级部门名称是否冲突
      // ~ 同级部门名称不可以重复，但是当前编辑的部门的名称可以重复 并且需要排除自己的id
      // ~ 在同级部门中进行筛选
      const info = depts.some(item => {
        // ~ 输入的内容 不能和同级部门名称一致 并且需要排除自己的id (不修改原数据)
        return item.name === value && item.id !== this.deptId.id
      })
      // ~ 3. 如果重复了 提示用户重复了 不可以修改
      if (info) {
        // ~ 重复了
        callback(new Error('同级部门名称不可以重复'))
      } else {
        // ~ 不重复什么也不做
        callback()
      }
    },
    // ~ --------- 规则 新修改的部门名称 不能和全局任何一个旧部门名称一致
    validateName (rule, value, callback) {
      // ~ 1. 进行some筛选 修改的部门不能和全局任何一个旧部门名称一致
      const info = this.allId.some(item => {
        // ~ 修改的内容 不能和同级部门名称一致 并且排除自身输入的名称(不修改原名称)
        return item.name === value && item.id !== this.deptId.id
      })
      // ~ 2. 如果重复了 提示用户重复了 不可以修改
      if (info) {
        // ~ 重复了
        callback(new Error('同级部门名称不可以重复'))
      } else {
        // ~ 不重复什么也不做
        callback()
      }
    },
    // 通知父组件关闭弹窗
    handleClose () {
      // 清空表单
      this.$refs.addForm.resetFields()
      // 通知父组件关闭弹窗
      this.$emit('update:is-show-dept-edit', false)
    },
    // 获取负责人列表数据
    async handleOpen () {
      try {
        // 获取部门负责人的信息
        const ret = await getEmployeeSimple()
        this.plist = ret.data
        // 上传需要编辑的组织架构 从服务器中获取其数据 赋值给form数据中 打印到页面上
        // 从服务器获取当前部门的数据
        const info = await reqGetDepartDetail(this.deptId.id)
        // 赋值给form数据中 打印到页面上
        this.form = info.data
        console.log(info)
      } catch {
        this.$message.error('获取负责人失败')
      }
    },
    // 设置提交修改后的数据
    addThis () {
      // 必须满足表单效验 才能提交数据
      this.$refs.addForm.validate(async valid => {
        if (valid) {
          try {
            // 如果满足条件 把数据上传到服务器
            await reqUpdateDepartments({
              // 把form里面的数据全部添加到服务器上
              ...this.form
            })
            // 关闭窗口，刷新列表
            this.handleClose()
            // 想父组件传值 让其刷新页面
            this.$emit('on-success')
          } catch (error) {
            this.$message.error('编辑部门失败')
          }
        }
      })
    }
  }
}
</script>
